package com.junxonline.plat.service.wages.impl;

import com.junxonline.common.exception.CommonBizException;
import com.junxonline.common.util.CommonUtils;
import com.junxonline.plat.dao.model.Wages;
import com.junxonline.plat.dao.model.Household;
import com.junxonline.plat.dao.repository.WagesRepository;
import com.junxonline.plat.dao.repository.HouseholdRepository;
import com.junxonline.plat.dao.vo.*;
import com.junxonline.plat.service.wages.WagesService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class WagesServiceImpl implements WagesService {

    private Logger logger = LogManager.getLogger();

    @Autowired
    private WagesRepository wagesRepository;

    @Autowired
    private HouseholdRepository householdRepository;

    /**
     * 获取工资数据
     *
     * @param vo
     * @return
     */
    @Override
    public WagesVO getWages(QueryWagesVO vo) {

        Wages wages = wagesRepository.findByWagesId(vo.getWagesId());

        WagesVO wagesVO = new WagesVO();
        wagesVO.setWagesId(wages.getWagesId());
        wagesVO.setWagesYearMonth(wages.getWagesYearMonth());
        wagesVO.setBaseWages(wages.getBaseWages());
        wagesVO.setBonusMoney(wages.getBonusMoney());
        wagesVO.setFullWorkMoney(wages.getFullWorkMoney());
        wagesVO.setOvertimeMoney(wages.getOvertimeMoney());
        wagesVO.setLaterMoney(wages.getLaterMoney());
        wagesVO.setAbsenteeismMoney(wages.getAbsenteeismMoney());
        wagesVO.setLeaveMoney(wages.getLeaveMoney());
        wagesVO.setAllWages(wages.getAllWages());

        Household household = wages.getPersonnel();
        if (CommonUtils.isNotEmpty(household)) {
            wagesVO.setHouseholdId(household.getHouseholdId());
            wagesVO.setHouseholdName(household.getHouseholdName());
            wagesVO.setHouseholdNo(household.getHouseholdNo());
        }

        return wagesVO;
    }

    /**
     * 筛选查询工资
     *
     * @param pageVO
     * @param vo
     * @return
     */
    @Override
    public PageVO queryWages(PageVO pageVO, QueryWagesVO vo) {

        PageRequest pageRequest = PageRequest.of(pageVO.getPage() - 1, pageVO.getLimit(), new Sort(Sort.Direction.ASC, "wagesId"));

        Page<Wages> page = wagesRepository.findAll(new Specification<Wages>() {
            @Override
            public Predicate toPredicate(Root<Wages> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                List<Predicate> params = new ArrayList<>();
                String personnelNo = vo.getHouseholdNo();
                String personnelName = vo.getHouseholdName();
                String wagesYearMonth = vo.getWagesYearMonth();

                Join householdMap = root.join("personnel", JoinType.LEFT);

                params.add(criteriaBuilder.equal(householdMap.get("isWorker"), 1));

                if (CommonUtils.isNotEmpty(personnelNo)) {
                    params.add(criteriaBuilder.like(householdMap.get("householdNo"), "%" + personnelNo + "%"));
                }

                if (CommonUtils.isNotEmpty(personnelName)) {
                    params.add(criteriaBuilder.like(householdMap.get("householdName"), "%" + personnelName + "%"));
                }

                if (CommonUtils.isNotEmpty(wagesYearMonth)) {
                    params.add(criteriaBuilder.like(root.get("wagesYearMonth").as(String.class), "%" + wagesYearMonth + "%"));
                }

                return criteriaBuilder.and(params.toArray(new Predicate[params.size()]));
            }
        }, pageRequest);

        List<WagesVO> wagesVOs = new ArrayList<>();
        List<Wages> wagess = page.getContent();

        for (Wages wages : wagess) {

            WagesVO wagesVO = new WagesVO();
            wagesVO.setWagesYearMonth(wages.getWagesYearMonth());
            wagesVO.setWagesId(wages.getWagesId());
            wagesVO.setBaseWages(wages.getBaseWages());
            wagesVO.setBonusMoney(wages.getBonusMoney());
            wagesVO.setFullWorkMoney(wages.getFullWorkMoney());
            wagesVO.setOvertimeMoney(wages.getOvertimeMoney());
            wagesVO.setLaterMoney(wages.getLaterMoney());
            wagesVO.setAbsenteeismMoney(wages.getAbsenteeismMoney());
            wagesVO.setLeaveMoney(wages.getLeaveMoney());
            wagesVO.setAllWages(wages.getAllWages());

            Household household = wages.getPersonnel();
            if (CommonUtils.isNotEmpty(household)) {
                wagesVO.setHouseholdId(household.getHouseholdId());
                wagesVO.setHouseholdName(household.getHouseholdName());
                wagesVO.setHouseholdNo(household.getHouseholdNo());
            }

            wagesVOs.add(wagesVO);
        }

        pageVO.setTotal(page.getTotalElements());
        pageVO.setData(wagesVOs);

        return pageVO;

    }

    /**
     * 添加工资
     *
     * @param vo
     * @return
     */
    @Override
    public boolean addWages(WagesVO vo) {

        Wages wages = new Wages();
        wages.setWagesYearMonth(vo.getWagesYearMonth());
        wages.setBaseWages(vo.getBaseWages());
        wages.setBonusMoney(vo.getBonusMoney());
        wages.setFullWorkMoney(vo.getFullWorkMoney());
        wages.setOvertimeMoney(vo.getOvertimeMoney());
        wages.setLaterMoney(vo.getLaterMoney());
        wages.setAbsenteeismMoney(vo.getAbsenteeismMoney());
        wages.setLeaveMoney(vo.getLeaveMoney());
        double allWages = wages.getBaseWages() + wages.getBonusMoney() + wages.getFullWorkMoney() + wages.getOvertimeMoney() - wages.getLaterMoney() - wages.getAbsenteeismMoney() - wages.getLeaveMoney();
        wages.setAllWages(allWages);

        Household personnel = householdRepository.findByHouseholdId(vo.getHouseholdId());

        if (CommonUtils.isEmpty(personnel)) {
            throw CommonBizException.SYSTEM_ERROR;
        }

        wages.setPersonnel(personnel);

        wagesRepository.save(wages);

        return true;
    }

    /**
     * 修改工资
     *
     * @param vo
     * @return
     */
    @Override
    public boolean editWages(WagesVO vo) {

        Wages wages = wagesRepository.findByWagesId(vo.getWagesId());

        wages.setWagesYearMonth(vo.getWagesYearMonth());
        wages.setBaseWages(vo.getBaseWages());
        wages.setBonusMoney(vo.getBonusMoney());
        wages.setFullWorkMoney(vo.getFullWorkMoney());
        wages.setOvertimeMoney(vo.getOvertimeMoney());
        wages.setLaterMoney(vo.getLaterMoney());
        wages.setAbsenteeismMoney(vo.getAbsenteeismMoney());
        wages.setLeaveMoney(vo.getLeaveMoney());
        double allWages = wages.getBaseWages() + wages.getBonusMoney() + wages.getFullWorkMoney() + wages.getOvertimeMoney() - wages.getLaterMoney() - wages.getAbsenteeismMoney() - wages.getLeaveMoney();
        wages.setAllWages(allWages);

        if (CommonUtils.isNotEmpty(vo.getHouseholdId())) {

            Household household = householdRepository.findByHouseholdId(vo.getHouseholdId());

            if (CommonUtils.isNotEmpty(household)) {
                wages.setPersonnel(household);
            }
        }

        wagesRepository.save(wages);

        return true;
    }

    /**
     * 删除工资
     *
     * @param wagesIds
     * @return
     */
    @Override
    public boolean delWages(Long[] wagesIds) {

        List<Wages> wagess = wagesRepository.findByWagesIdIn(wagesIds);

        for (Wages wages : wagess) {
            // 删除工资
            wagesRepository.delete(wages);
        }


        return true;
    }


    /**
     * 获取员工数据
     *
     * @param vo
     * @return
     */
    @Override
    public List<HouseholdVO> getHousehold(QueryHouseholdVO vo) {

        List<HouseholdVO> householdVOList = new ArrayList<>();
        List<Household> households = householdRepository.findByHouseholdNameLikeAndIsWorker(vo.getHouseholdName(), 1);

        for (Household household : households) {

            HouseholdVO householdVO = new HouseholdVO();
            householdVO.setHouseholdId(household.getHouseholdId());
            householdVO.setHouseholdName(household.getHouseholdName());
            householdVO.setHouseholdNo(household.getHouseholdNo());
            householdVOList.add(householdVO);
        }

        return householdVOList;
    }

}
